﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;

namespace parking
{
    public class GarageImpl
    {
        static dbDataContext db = new dbDataContext();

        internal static string getGarageList()
        {
            
            //get the list of garages from the database
            var garages = from g in db.garages
                          select g;

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            XmlNode garagesNode = doc.CreateElement("garages");
            doc.AppendChild(garagesNode);

            //add individual garages into the xml
            foreach (var garage in garages)
            {
                XmlNode garageNode = doc.CreateElement("garage");

                //add garageId
                XmlAttribute attr = doc.CreateAttribute("id");
                attr.Value = garage.garageId.ToString();
                garageNode.Attributes.Append(attr);

                //add name
                attr = doc.CreateAttribute("name");
                attr.Value = garage.name.ToString();
                garageNode.Attributes.Append(attr);

                //add address
                attr = doc.CreateAttribute("address");
                attr.Value = garage.address.ToString();
                garageNode.Attributes.Append(attr);

                //add city
                attr = doc.CreateAttribute("city");
                attr.Value = garage.city.ToString();
                garageNode.Attributes.Append(attr);

                //add state
                attr = doc.CreateAttribute("state");
                attr.Value = garage.state.ToString();
                garageNode.Attributes.Append(attr);

                //add zip
                attr = doc.CreateAttribute("zip");
                attr.Value = garage.zip.ToString();
                garageNode.Attributes.Append(attr);

                //append to the parent node
                garagesNode.AppendChild(garageNode);
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();
        }


        internal static int getFloorCount(int garageId)
        {
            //get the the garage from the database
            int floorCount = (from g in db.garages
                          where g.garageId == garageId
                          select g.floor).FirstOrDefault();

            return floorCount;

            
        }

        internal static string getAvailableGarage(string starttime, string endtime)
        {
            var garages = db.Get_Available_Garages(Convert.ToDateTime(starttime), Convert.ToDateTime(endtime));

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            XmlNode garagesNode = doc.CreateElement("garages");
            doc.AppendChild(garagesNode);

            //add individual garages into the xml
            foreach (var garage in garages)
            {
                XmlNode garageNode = doc.CreateElement("garage");

                //add garageId
                XmlAttribute attr = doc.CreateAttribute("id");
                attr.Value = garage.garageId.ToString();
                garageNode.Attributes.Append(attr);

                //add name
                attr = doc.CreateAttribute("name");
                attr.Value = garage.name.ToString();
                garageNode.Attributes.Append(attr);

                //add address
                attr = doc.CreateAttribute("address");
                attr.Value = garage.address.ToString();
                garageNode.Attributes.Append(attr);

                //add city
                attr = doc.CreateAttribute("city");
                attr.Value = garage.city.ToString();
                garageNode.Attributes.Append(attr);

                //add state
                attr = doc.CreateAttribute("state");
                attr.Value = garage.state.ToString();
                garageNode.Attributes.Append(attr);

                //add zip
                attr = doc.CreateAttribute("zip");
                attr.Value = garage.zip.ToString();
                garageNode.Attributes.Append(attr);

                //append to the parent node
                garagesNode.AppendChild(garageNode);
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();



        }

        internal static string getSpotList(int garageId, int floor)
        {
            //get the the garage from the database
            garage garage = (from g in db.garages
                        where g.garageId == garageId
                        select g).FirstOrDefault();
            
            //get the spots from the database
            var spots = from s in db.spots
                            where s.floor == floor && s.garageId == garageId
                            select s;

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            //construct the garage node
            XmlNode garageNode = doc.CreateElement("garage");
            doc.AppendChild(garageNode);

            //add garageId
            XmlAttribute attr = doc.CreateAttribute("id");
            attr.Value = garage.garageId.ToString();
            garageNode.Attributes.Append(attr);

            //add name
            attr = doc.CreateAttribute("name");
            attr.Value = garage.name.ToString();
            garageNode.Attributes.Append(attr);

            //add address
            attr = doc.CreateAttribute("address");
            attr.Value = garage.address.ToString();
            garageNode.Attributes.Append(attr);

            //add city
            attr = doc.CreateAttribute("city");
            attr.Value = garage.city.ToString();
            garageNode.Attributes.Append(attr);

            //add state
            attr = doc.CreateAttribute("state");
            attr.Value = garage.state.ToString();
            garageNode.Attributes.Append(attr);

            //add zip
            attr = doc.CreateAttribute("zip");
            attr.Value = garage.zip.ToString();
            garageNode.Attributes.Append(attr);

            //add the floor node
            XmlNode floorNode = doc.CreateElement("floor");
            garageNode.AppendChild(floorNode);

            attr = doc.CreateAttribute("number");
            attr.Value = floor.ToString();
            floorNode.Attributes.Append(attr);

            //add the spot list into XML
            foreach (var spot in spots)
            {
                XmlNode spotNode = doc.CreateElement("spot");

                //add spotId
                attr = doc.CreateAttribute("id");
                attr.Value = spot.spotId.ToString();
                spotNode.Attributes.Append(attr);

                // add status
                attr = doc.CreateAttribute("status");
                attr.Value = spot.status.ToString();
                spotNode.Attributes.Append(attr);
                
                //add to the parent node
                floorNode.AppendChild(spotNode);
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();

        }

        internal static string getAvailableSpotByFloor(string starttime, string endtime, int garageId, int floor)
        {
            //get the the garage from the database
            garage garage = (from g in db.garages
                             where g.garageId == garageId
                             select g).FirstOrDefault();

            //TODO: 
            //get the spots from the database
            var spots = db.Get_Available_Spots_By_GarageFloor(Convert.ToDateTime(starttime), Convert.ToDateTime(endtime), garageId, floor);
            
            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            //construct the garage node
            XmlNode garageNode = doc.CreateElement("garage");
            doc.AppendChild(garageNode);

            //add garageId
            XmlAttribute attr = doc.CreateAttribute("id");
            attr.Value = garage.garageId.ToString();
            garageNode.Attributes.Append(attr);

            //add name
            attr = doc.CreateAttribute("name");
            attr.Value = garage.name.ToString();
            garageNode.Attributes.Append(attr);

            //add address
            attr = doc.CreateAttribute("address");
            attr.Value = garage.address.ToString();
            garageNode.Attributes.Append(attr);

            //add city
            attr = doc.CreateAttribute("city");
            attr.Value = garage.city.ToString();
            garageNode.Attributes.Append(attr);

            //add state
            attr = doc.CreateAttribute("state");
            attr.Value = garage.state.ToString();
            garageNode.Attributes.Append(attr);

            //add zip
            attr = doc.CreateAttribute("zip");
            attr.Value = garage.zip.ToString();
            garageNode.Attributes.Append(attr);

            //add the floor node
            XmlNode floorNode = doc.CreateElement("floor");
            garageNode.AppendChild(floorNode);

            attr = doc.CreateAttribute("number");
            attr.Value = floor.ToString();
            floorNode.Attributes.Append(attr);

            //add the spot list into XML
            foreach (var spot in spots)
            {
                XmlNode spotNode = doc.CreateElement("spot");

                //add spotId
                attr = doc.CreateAttribute("id");
                attr.Value = spot.spotId.ToString();
                spotNode.Attributes.Append(attr);

                // add status
                attr = doc.CreateAttribute("status");
                attr.Value = spot.status.ToString();
                spotNode.Attributes.Append(attr);

                //add to the parent node
                floorNode.AppendChild(spotNode);
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();
        }


        internal static string getAvailableSpotByFloorAndUserType(string starttime, string endtime, int garageId, int floor, int userType)
        {
            //get the the garage from the database
            garage garage = (from g in db.garages
                             where g.garageId == garageId
                             select g).FirstOrDefault();

            //get the spots from the database
            var spots = db.Get_Available_Spots_By_GarageFloor_And_UserType(Convert.ToDateTime(starttime), Convert.ToDateTime(endtime), garageId, floor, userType);

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            //construct the garage node
            XmlNode garageNode = doc.CreateElement("garage");
            doc.AppendChild(garageNode);

            //add garageId
            XmlAttribute attr = doc.CreateAttribute("id");
            attr.Value = garage.garageId.ToString();
            garageNode.Attributes.Append(attr);

            //add name
            attr = doc.CreateAttribute("name");
            attr.Value = garage.name.ToString();
            garageNode.Attributes.Append(attr);

            //add address
            attr = doc.CreateAttribute("address");
            attr.Value = garage.address.ToString();
            garageNode.Attributes.Append(attr);

            //add city
            attr = doc.CreateAttribute("city");
            attr.Value = garage.city.ToString();
            garageNode.Attributes.Append(attr);

            //add state
            attr = doc.CreateAttribute("state");
            attr.Value = garage.state.ToString();
            garageNode.Attributes.Append(attr);

            //add zip
            attr = doc.CreateAttribute("zip");
            attr.Value = garage.zip.ToString();
            garageNode.Attributes.Append(attr);

            //add the floor node
            XmlNode floorNode = doc.CreateElement("floor");
            garageNode.AppendChild(floorNode);

            attr = doc.CreateAttribute("number");
            attr.Value = floor.ToString();
            floorNode.Attributes.Append(attr);

            //add the spot list into XML
            foreach (var spot in spots)
            {
                XmlNode spotNode = doc.CreateElement("spot");

                //add spotId
                attr = doc.CreateAttribute("id");
                attr.Value = spot.spotId.ToString();
                spotNode.Attributes.Append(attr);

                // add status
                attr = doc.CreateAttribute("status");
                attr.Value = spot.status.ToString();
                spotNode.Attributes.Append(attr);

                //add to the parent node
                floorNode.AppendChild(spotNode);
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();
        }

        internal static string getAvailableSpot(string starttime, string endtime, int garageId)
        {
            //get the the garage from the database
            garage garage = (from g in db.garages
                             where g.garageId == garageId
                             select g).FirstOrDefault();

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            //construct the garage node
            XmlNode garageNode = doc.CreateElement("garage");
            doc.AppendChild(garageNode);

            //add garageId
            XmlAttribute attr = doc.CreateAttribute("id");
            attr.Value = garage.garageId.ToString();
            garageNode.Attributes.Append(attr);

            //add name
            attr = doc.CreateAttribute("name");
            attr.Value = garage.name.ToString();
            garageNode.Attributes.Append(attr);

            //add address
            attr = doc.CreateAttribute("address");
            attr.Value = garage.address.ToString();
            garageNode.Attributes.Append(attr);

            //add city
            attr = doc.CreateAttribute("city");
            attr.Value = garage.city.ToString();
            garageNode.Attributes.Append(attr);

            //add state
            attr = doc.CreateAttribute("state");
            attr.Value = garage.state.ToString();
            garageNode.Attributes.Append(attr);

            //add zip
            attr = doc.CreateAttribute("zip");
            attr.Value = garage.zip.ToString();
            garageNode.Attributes.Append(attr);


            // ADD THE SPOTS FLOOR BY FLOOR

            //get the number of floors
            int floorCount = garage.floor;

            for(int i=1; i<=floorCount; i++)
            {
                //get the spots from the database
                var spots = db.Get_Available_Spots_By_GarageFloor(Convert.ToDateTime(starttime), Convert.ToDateTime(endtime), garageId, i);


                //add the floor node
                XmlNode floorNode = doc.CreateElement("floor");
                garageNode.AppendChild(floorNode);

                attr = doc.CreateAttribute("number");
                attr.Value = i.ToString();
                floorNode.Attributes.Append(attr);

                //add the spot list into XML
                foreach (var spot in spots)
                {
                    XmlNode spotNode = doc.CreateElement("spot");

                    //add spotId
                    attr = doc.CreateAttribute("id");
                    attr.Value = spot.spotId.ToString();
                    spotNode.Attributes.Append(attr);

                    // add status
                    attr = doc.CreateAttribute("status");
                    attr.Value = spot.status.ToString();
                    spotNode.Attributes.Append(attr);

                    //add to the parent node
                    floorNode.AppendChild(spotNode);
                }
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();
        }


        internal static string getAvailableSpotByUserType(string starttime, string endtime, int garageId, int userType)
        {
            //get the the garage from the database
            garage garage = (from g in db.garages
                             where g.garageId == garageId
                             select g).FirstOrDefault();

            //create the root node of the xml
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            //construct the garage node
            XmlNode garageNode = doc.CreateElement("garage");
            doc.AppendChild(garageNode);

            //add garageId
            XmlAttribute attr = doc.CreateAttribute("id");
            attr.Value = garage.garageId.ToString();
            garageNode.Attributes.Append(attr);

            //add name
            attr = doc.CreateAttribute("name");
            attr.Value = garage.name.ToString();
            garageNode.Attributes.Append(attr);

            //add address
            attr = doc.CreateAttribute("address");
            attr.Value = garage.address.ToString();
            garageNode.Attributes.Append(attr);

            //add city
            attr = doc.CreateAttribute("city");
            attr.Value = garage.city.ToString();
            garageNode.Attributes.Append(attr);

            //add state
            attr = doc.CreateAttribute("state");
            attr.Value = garage.state.ToString();
            garageNode.Attributes.Append(attr);

            //add zip
            attr = doc.CreateAttribute("zip");
            attr.Value = garage.zip.ToString();
            garageNode.Attributes.Append(attr);


            // ADD THE SPOTS FLOOR BY FLOOR

            //get the number of floors
            int floorCount = garage.floor;

            for (int i = 1; i <= floorCount; i++)
            {
                //get the spots from the database
                var spots = db.Get_Available_Spots_By_GarageFloor_And_UserType(Convert.ToDateTime(starttime), Convert.ToDateTime(endtime), garageId, i, userType);

                //add the floor node
                XmlNode floorNode = doc.CreateElement("floor");
                garageNode.AppendChild(floorNode);

                attr = doc.CreateAttribute("number");
                attr.Value = i.ToString();
                floorNode.Attributes.Append(attr);

                //add the spot list into XML
                foreach (var spot in spots)
                {
                    XmlNode spotNode = doc.CreateElement("spot");

                    //add spotId
                    attr = doc.CreateAttribute("id");
                    attr.Value = spot.spotId.ToString();
                    spotNode.Attributes.Append(attr);

                    // add status
                    attr = doc.CreateAttribute("status");
                    attr.Value = spot.status.ToString();
                    spotNode.Attributes.Append(attr);

                    //add to the parent node
                    floorNode.AppendChild(spotNode);
                }
            }

            //convert the XML into string
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

            doc.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();

            return stringWriter.GetStringBuilder().ToString();
        }
    }
}